package com.sudo.service.admin.service.impl;

import com.sudo.common.enums.SysJobAction;
import com.sudo.common.enums.SysJobResult;
import com.sudo.common.enums.SysStatus;
import com.sudo.common.utils.*;
import com.sudo.dao.admin.entity.SysJobLog;
import com.sudo.dao.admin.mapper.SysJobLogMapper;
import com.sudo.rpc.api.utils.RpcRes;
import com.sudo.service.admin.mail.MailPojo;
import com.sudo.service.admin.mail.MailPojoUtil;
import com.sudo.service.admin.mail.MailService;
import com.sudo.service.admin.service.LogAndEmailService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * @Author：DayDayUp
 * @Create：2023/2/11 15:13
 */
@Slf4j
@Service
public class LogAndEmailServiceImpl implements LogAndEmailService {
    @Resource
    private SysJobLogMapper sysJobLogMapper;
    @Resource
    private MailService mailService;

    @Override
    public void asyncLocalMethodJobLogAndEmail(JsonRes jsonRes,SysJobAction sysJobAction) {
        Map<String, Object> tlMap = ThreadLocalUtil.getTlMap();
        ThreadLocalUtil.removeTlMap();
        ThreadExecutor.execute(()->{
            setJobLogAndEmail(tlMap, jsonRes.getStatus(), jsonRes.getMsg(), jsonRes.getData(), sysJobAction);
        });
    }

    @Override
    public void asyncRpcMethodJobLogAndEmail(Map<String, Object> tlMap,RpcRes rpcRes) {
        HttpServletResponse response = HttpServletUtil.getResponse();
        ThreadExecutor.execute(()->{
            if (response == null) {
                setJobLogAndEmail(tlMap, rpcRes.getStatus(), rpcRes.getMsg(), rpcRes.getData(),SysJobAction.AUTO);
            }else {
                setJobLogAndEmail(tlMap, rpcRes.getStatus(), rpcRes.getMsg(), rpcRes.getData(),SysJobAction.MANUAL);
            }
        });
    }


    private void setJobLogAndEmail(Map<String, Object> tlMap, Integer status,String msg,Object data,SysJobAction sysJobAction){

        Integer jobId = Integer.parseInt(tlMap.get("tl_jobId").toString());
        Object tlJobServer = tlMap.get("tl_jobServer");
        String jobServer = null;
        if (tlJobServer != null){
            jobServer = tlJobServer.toString();
        }
        String jobBean = tlMap.get("tl_jobBean").toString();
        String jobMethod = tlMap.get("tl_jobMethod").toString();
        Object tlJobParams = tlMap.get("tl_jobParams");
        String jobParams = null;
        if (tlJobParams != null){
            jobParams = tlJobParams.toString();
        }
        String logStatus = tlMap.get("tl_logStatus").toString();
        String mailStatus = tlMap.get("tl_mailStatus").toString();
        String jobResult = status == 200 ? SysJobResult.SUCCESS.name() : SysJobResult.FAIL.name();
        LocalDateTime jobStartTime = (LocalDateTime)tlMap.get("tl_jobStartTime");
        LocalDateTime jobEndTime = LocalDateTime.now();
        String jobStartTimeStr = LocalDateTimeUtil.convertLocateDateTime2Str(jobStartTime,LocalDateTimeUtil.yyyy_MM_dd_HH_mm_ss_SSS);
        String jobEndTimeStr = LocalDateTimeUtil.convertLocateDateTime2Str(jobEndTime,LocalDateTimeUtil.yyyy_MM_dd_HH_mm_ss_SSS);

        SysJobLog sysJobLog = new SysJobLog();
        sysJobLog.setJobId(jobId);
        sysJobLog.setJobServer(jobServer);
        sysJobLog.setJobBean(jobBean);
        sysJobLog.setJobMethod(jobMethod);
        sysJobLog.setJobParams(jobParams);
        sysJobLog.setJobResult(jobResult);
        sysJobLog.setJobNote(msg);
        if (data == null) {
            data = "";
        }
        sysJobLog.setJobNoteDesc(data.toString());
        sysJobLog.setJobStartTime(jobStartTimeStr);
        sysJobLog.setJobEndTime(jobEndTimeStr);
        Duration between = Duration.between(jobStartTime, jobEndTime);
        long useTime = between.toMillis();
        sysJobLog.setJobUseTime(useTime);
        sysJobLog.setJobType(tlMap.get("tl_jobType").toString());
        sysJobLog.setJobAction(sysJobAction.name());
        sysJobLog.setCreateTime(LocalDateTimeUtil.getStandardDateTimeStr());

        // 是否记录日志
        ThreadExecutor.execute(()->{
            if (SysStatus.ON.name().equals(logStatus)){
                // 日志写入Mysql
                sysJobLogMapper.insertSelective(sysJobLog);
            }
        });


        // 执行失败则发送邮件提醒
        if (SysJobResult.FAIL.name().equals(jobResult)) {
            // 是否发邮件提醒
            ThreadExecutor.execute(() -> {
                Object mailAddressObject = tlMap.get("tl_mailAddress");
                if (mailAddressObject != null) {
                    String mailAddress = mailAddressObject.toString();
                    if (StringUtils.isNotBlank(mailAddress)
                            && SysStatus.ON.name().equals(mailStatus)
                            && jobResult.equals(SysJobResult.FAIL.name())) {
                        MailPojo mailPojo = MailPojoUtil.methodJobExceptionMail(mailAddress, sysJobLog);
                        mailService.sendMimeMail(mailPojo);
                    }
                }
            });
        }
    }

}
